﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using WCFLOBTalk.SalesForceWCF.SFService;

namespace WCFLOBTalk.SalesForceWCF.Helpers
{
    public class SFHelper
    {

        private static SforceService serviceInstance = null;
        static string instanceName = "";

        private static DateTime LastBuilt = DateTime.Now;

        public static bool IsStillValidConnection()
        {
            bool ret = false;

            if (LastBuilt.AddHours(2) > DateTime.Now)
            {
                ret = true;
            }

            return ret;
        }

        public static SforceService Login(string url, string userName, string password, string securityToken, bool isMetadataUrl, string version)
        {
            //MessageBox.Show("Inside SFHelper.Login");


            if (serviceInstance == null || (LastBuilt.AddHours(2) < DateTime.Now))
            {
                // 
                
                
                SFService.SforceService c = new SforceService();
                // replace the scheme with http
                string newUrl = url.Replace("salesforcewcf", "https");
                newUrl = newUrl.Split(Convert.ToChar("?")).GetValue(0).ToString();
                //url = url + "/" + version;
                c.Url = newUrl;

                //MessageBox.Show(String.Format("url: {0}, username: {1}, password: {2}, securityToken: {3}, version: {4}", newUrl, userName, password, securityToken, version));

                c.Timeout = 60000;

                LoginResult lr = null;
                // Alternate entry point for calling from .NET
                lr = c.login(userName, password + securityToken);

                //MessageBox.Show("login successful!");

                if (isMetadataUrl)
                {
                    c.Url = lr.metadataServerUrl;
                }
                else
                {
                    // normally this
                    c.Url = lr.serverUrl;
                }
                c.SessionHeaderValue = new SessionHeader();
                c.SessionHeaderValue.sessionId = lr.sessionId;
                serviceInstance = c;
                LastBuilt = DateTime.Now;

                // parse the instance name
                string instance = c.Url;
                instance = instance.Replace("https://", "");
                string[] urlParts = instance.Split(Convert.ToChar("/"));
                if (urlParts.Length > 0)
                {
                    string domain = urlParts[0];
                    string[] domainParts = domain.Split(Convert.ToChar("."));
                    if (domainParts.Length > 0)
                    {
                        string firstPart = domainParts[0];
                        firstPart = firstPart.Replace("-api", "");
                        instanceName = firstPart;
                        System.Diagnostics.Debug.WriteLine(String.Format("instance name: {0}", instanceName));
                    }
                }

            }
            //MessageBox.Show("returning the service instance now");

            return serviceInstance;

        }

        public static SFMetadata RetrieveMetadata(SforceService connectionInstance) {

            bool IsInternetConnected = false;

            SFMetadata sfm = new SFMetadata();

            if (IsInternetConnected)
            {

                sfm = new SFMetadata();
                List<SFObjectType> types = new List<SFObjectType>();

                // Populate types
                //DescribeGlobalResult dgr = connectionInstance.describeGlobal();

                DescribeSObjectResult[] dgr = connectionInstance.describeSObjects(new string[] { "Account", "Contact" });
                for (int i = 0; i < dgr.Length; i++)
                {
                    DescribeSObjectResult d = dgr.GetValue(i) as DescribeSObjectResult;

                    SFObjectType st = new SFObjectType() { Name = d.name };

                    // Get the method details for this object

                    Account a = new Account();
                    Contact c = new Contact();
                    // if (d.name.Equals("Account")) { o = Activator.CreateInstance<Account>(); }
                    MethodInfo[] mis = null;
                    if (d.name.Equals("Account"))
                    {
                        mis = a.GetType().GetMethods();
                    }
                    else
                    {
                        mis = c.GetType().GetMethods();
                    }

                    List<string> methods = new List<string>();

                    foreach (MethodInfo mi in mis)
                    {
                        methods.Add(mi.Name);
                    }

                    // Remove any that don't make sense.

                    st.Methods = methods;
                    types.Add(st);

                }
                sfm.Types = types;
            }
            else
            {
                XmlSerializer x = new XmlSerializer(typeof(SFMetadata));
                StreamReader rd = new StreamReader(@"C:\Documents and Settings\Administrator\Desktop\SFnodes.xml");
                sfm = x.Deserialize(rd) as SFMetadata; 

            }
            // Populate other metadata types



            return sfm;
        }

    }
    [XmlRoot()]
    public class SFMetadata
    {
        [XmlArray(ElementName="Types")]
        public List<SFObjectType> Types = new List<SFObjectType>();

        public SFMetadata() { }

        public SFMetadata(List<SFObjectType> types)
        {
            Types = types;
        }
    }

    
    public class SFObjectType
    {
        [XmlElement()]
        public string Name { get; set; }
        [XmlArray(ElementName="Methods")]
        public List<string> Methods { get; set; }
        
    }
    public class SFMethods
    {
        public List<string> Methods = new List<string>();

    }
}
